package com.xxwy.dependency.lookup;

import com.xxwy.dependency.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Map;

/**
 * 类型安全的 依赖查找实例
 *
 * @author wy
 * @date 2020/4/22 17:31
 */
public class TypeSafetyDedencyDemo {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    applicationContext.register(ObjectProviderDemo.class);
    applicationContext.refresh();
    // BeanFactory非安全报错：error
    displayBeanFactoryGetBean(applicationContext.getBeanFactory());

    //ObjectFactory#getObject(): error
    displayObjectFactoryGetBean(applicationContext.getBeanProvider(User.class));

    //TODO:ObjectProvider#getIfAvailable() ok
    displayObjectProviderGetBean(applicationContext.getBeanProvider(User.class));

    //------集合-------
    //TODO:ObjectProvider#getIfAvailable() ok
    displayListableBeanFactoryGetBean(applicationContext);

    //TODO:ObjectProvider#stream() ok
    displayObjectProviderStream(applicationContext);



    applicationContext.close();

  }

  private static void displayObjectProviderStream(AnnotationConfigApplicationContext applicationContext) {
    printBeansException("ObjectProviderStream#stream()",()->{
      ObjectProvider<User> beanProvider = applicationContext.getBeanProvider(User.class);
      beanProvider.stream().forEach(System.out::println);
    });
  }

  private static void displayListableBeanFactoryGetBean(AnnotationConfigApplicationContext applicationContext) {
    printBeansException("ListableBeanFactory#getBeansOfType",()->{
      Map<String, User> beans = applicationContext.getBeansOfType(User.class);
    });
  }

  private static <T> void displayObjectFactoryGetBean(ObjectProvider<T> beanProvider) {
    printBeansException("ObjectFactory#getObject", () -> {
      T t = beanProvider.getObject();
    });
  }

  private static <T> void displayObjectProviderGetBean(ObjectProvider<T> beanProvider) {
    printBeansException("ObjectProvider#getIfAvailable", () -> {
      T t = beanProvider.getIfAvailable();
    });

  }


  private static void displayBeanFactoryGetBean(ConfigurableListableBeanFactory beanFactory) {
    printBeansException("BeanFactory", () -> {
      beanFactory.getBean(User.class);
    });
  }

  private static void printBeansException(String name, Runnable runnable) {
    try {
      runnable.run();
    } catch (Exception e) {
      System.out.println(name + " error");
    }
  }

}
